home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 November
/
Macworld (1999-11).dmg
/
Shareware World
/
Comms & Internet
/
DXF to VRML97 1.0.1
/
src
/
dxf2vrml97.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-08-24
|
7KB
|
346 lines
// Original code from DIME distribtion, available from http://www.sim.no/
// Released under GPL v2 (see the DIME distribution)
// Converted from VRML 1.0 to ISO VRML 97 and prepared to work
// nicely with DropUnix by Michael.Louka@hrp.no
#include <dime/entities/Entity.h>
#include <dime/Input.h>
#include <dime/Model.h>
#include <dime/State.h>
#include <dime/util/BSPTree.h>
#include <stdlib.h>
#ifdef macintosh
#include "console.h"
#include "unix.h"
#include "SIOUX.h"
#include "Main.h"
#endif
class faceset_data {
public:
faceset_data() {
}
~faceset_data() {
}
void clean() {
bspTree.clear();
indices.makeEmpty();
}
public:
dimeArray <int> indices;
dimeBSPTree bspTree;
};
// some static arrays
static dimeArray <int> indexarray;
static dimeArray <dimeVec3f> vertexarray;
static faceset_data *facesets;
static bool my_dime_callback(const dimeState * const state,
dimeEntity *entity, void *);
static void convertColor(faceset_data *data, const int colnum, FILE *out);
//
// Call this to initialize static members.
//
static void
init()
{
if (facesets) delete [] facesets;
facesets = new faceset_data[255];
}
//
// Call this to free static data.
//
static void
end()
{
delete [] facesets;
facesets = NULL;
indexarray.makeEmpty();
vertexarray.makeEmpty();
}
static bool
convertDxf2Wrl(const char * const dxffilename,
const char * const wrlfilename)
{
dimeInput in;
if (!in.setFile(dxffilename)) {
return false;
}
dimeModel model;
if (!model.read(&in)) {
fprintf(stderr,"Read error in line: %d\n", in.getFilePosition());
return false;
}
FILE *out = fopen(wrlfilename, "w");
if (!out) return false;
fprintf(out,
"#VRML V2.0 utf8\n\n"
"Group {\n children [\n");
model.traverseEntities(my_dime_callback, &model,
false, true, false);
for (int i = 0; i < 255; i++) {
convertColor(&facesets[i], i+1, out);
}
fprintf(out," ]\n}\n");
return true;
}
static void
convertColor(faceset_data *data, const int colnum, FILE *out)
{
int i;
int icnt = data->indices.count();
int vcnt = data->bspTree.numPoints();
if (vcnt == 0 || icnt == 0) return;
// If not present, append a -1 at the end of the index array
if (data->indices[icnt-1] >= 0) data->indices.append(-1);
dimeBSPTree &bsptree = data->bspTree;
fprintf(out," Shape {\n");
float r, g, b;
dimeLayer::colorToRGB(colnum, r, g, b);
fprintf(out," appearance Appearance {\n"
" material Material {\n"
" diffuseColor %g %g %g\n"
" specularColor 1 1 1\n"
" }\n }\n", r,g,b);
fprintf(out," geometry IndexedFaceSet {\n"
" solid FALSE\n"
" coord Coordinate {\n"
" point [\n");
int first = 1;
for (i = 0; i < vcnt; i++) {
dimeVec3f tmp;
bsptree.getPoint(i, tmp);
if (first) {
fprintf(out," %g %g %g", tmp[0], tmp[1], tmp[2]);
first = 0;
}
else
fprintf(out,",\n %g %g %g", tmp[0], tmp[1], tmp[2]);
}
fprintf(out,"\n ]\n }\n");
bsptree.clear();
if (icnt) {
fprintf(out," coordIndex [\n ");
int *ptr = data->indices.arrayPointer();
int facecnt = 1;
for (i = 0; i < icnt-1; i++) {
int index = *ptr++;
fprintf(out, "%d,", index);
if (index < 0) {
facecnt++;
if ((facecnt & 3) == 0) fprintf(out,"\n ");
}
}
fprintf(out, "-1\n ]\n }\n");
data->indices.makeEmpty(); // free memory
}
fprintf(out," }\n");
}
static int
get_color_index(dimeEntity *entity)
{
int colnum = entity->getColorNumber();
if (colnum == 256) {
const dimeLayer *layer = entity->getLayer();
colnum = layer->getColorNumber();
}
return colnum;
}
bool
my_dime_callback(const dimeState * const state,
dimeEntity *entity, void *)
{
static int blockcolidx = 7; // to support BYBLOCK color
dimeMatrix matrix = state->getMatrix();
indexarray.setCount(0);
vertexarray.setCount(0);
float thickness;
dimeVec3f extrusionDir;
dimeEntity::GeometryType type =
entity->extractGeometry(vertexarray,
indexarray,
extrusionDir,
thickness);
if (type == dimeEntity::NONE) return true;
int id = entity->typeId();
if (extrusionDir != dimeVec3f(0,0,1)) {
if (id == dimeBase::dimeTraceType ||
id == dimeBase::dimeSolidType ||
id == dimeBase::dimeCircleType ||
thickness == 0.0) {
dimeMatrix m;
dimeEntity::generateUCS(extrusionDir, m);
matrix.multRight(m);
}
}
int colidx = get_color_index(entity);
if (colidx == 0) { // BYBLOCK
colidx = blockcolidx;
}
// negative color means layer turned off, but who cares
if (colidx < 0) colidx = -colidx;
colidx--; // to use lookup table
if (colidx < 0 || colidx > 255) { // safety check
colidx = 6; // should never happen
}
dimeBSPTree &bsp = facesets[colidx].bspTree;
dimeArray <int> &idx = facesets[colidx].indices;
int i,n,numidx;
n = vertexarray.count();
numidx = indexarray.count();
if (n == 0) return true;
switch(type) {
case dimeEntity::POLYGONS:
//
// Extruded polygons not supported
//
if (numidx == 0) {
for (i = 0; i < n; i++) {
dimeVec3f tmp = vertexarray[i];
matrix.multMatrixVec(tmp);
idx.append(bsp.addPoint(tmp));
}
idx.append(-1);
}
else {
for (i = 0; i < numidx; i++) {
int index = indexarray[i];
if (index >= 0) {
dimeVec3f tmp = vertexarray[index];
matrix.multMatrixVec(tmp);
idx.append(bsp.addPoint(tmp));
}
else idx.append(-1);
}
if (idx.count() && idx[idx.count()-1] >= 0)
idx.append(-1);
}
break;
case dimeEntity::LINES:
case dimeEntity::POINTS:
// just insert code here :-)
break;
default:
break;
}
return true;
}
int main(int argc, char **argv)
{
#ifdef macintosh
SIOUXSettings.asktosaveonclose = 0;
_fcreator = 'CMPL';
_ftype = 'TEXT';
#endif
for (int i = 1; i <= (argc - 1); i++) {
init();
// Construct the full filepath for the VRML file:
char* dxfFullPath = argv[i];
char* wrlFileName = new char[32];
char* wrlFullPath = new char[strlen(dxfFullPath)+4];
strcpy (wrlFullPath, dxfFullPath);
if (wrlFileName != NULL ) {
char* sPos;
char* ePos;
sPos = strrchr( dxfFullPath, ':' );
if ( sPos != NULL )
sPos++;
else
sPos = (char*)dxfFullPath;
strncpy( wrlFileName, sPos, 26 );
ePos = strstr( wrlFileName+1, ".dxf" );
if ( ePos == NULL )
ePos = strstr( wrlFileName+1, ".DXF" );
if ( ePos != NULL )
*ePos = '\0';
strcat(wrlFileName,".wrl");
sPos = strrchr( wrlFullPath, ':' );
if ( sPos != NULL ) {
sPos++;
strcpy (sPos, wrlFileName);
}
else {
free (wrlFullPath);
wrlFullPath = wrlFileName;
}
// Do the conversion
if (!convertDxf2Wrl(dxfFullPath, wrlFullPath)) {
fprintf(stderr,"Error while converting.\n");
}
if (wrlFileName)
free (wrlFileName);
if (wrlFullPath)
free (wrlFullPath);
}
end();
}
exit(1);
}